//===============================================================================
// Microsoft patterns & practices
// Guidance Explorer Offline Client
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================



using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;


namespace GuidanceExplorer.Model
{
    /// <summary>
    /// Represents a view which is a collection of items from any library in the model.
    /// </summary>
    public class View : ILibraryNodes
    {
        /// <summary>
        /// Factory.
        /// </summary>
        /// <returns>A new instance of a View.</returns>
        public static View New()
        {
            return new View();
        }

        #region Private members

        /// <summary>
        /// The list of items in the view.
        /// </summary>
        private GuidanceItemCollection _items = GuidanceItemCollection.New();

        /// <summary>
        /// The parent folder reference.
        /// </summary>
        private Folder _parentFolder;

        /// <summary>
        /// The outer container of the view.
        /// </summary>
        private FolderStructure _container;

        /// <summary>
        /// The columns for this view.
        /// </summary>
        protected ColumnCollection _columns = ColumnCollection.New();

        /// <summary>
        /// The caption of the view.
        /// </summary>
        private string _caption;

        /// <summary>
        /// The unique id of the view.
        /// </summary>
        protected string _id = Guid.NewGuid().ToString();

        /// <summary>
        /// The author of the view.
        /// </summary>
        private string _author;

        /// <summary>
        /// The description of this view.
        /// </summary>
        private string _description;

        /// <summary>
        /// The creation date for this view.
        /// </summary>
        private DateTime _lastUpdate;

        /// <summary>
        /// Whether the view will be display as a root element or within the container.
        /// </summary>
        private bool _rootView;


        #endregion

        /// <summary>
        /// Default private constructor.
        /// </summary>
        protected View() { }


        #region Public Properties

        /// <summary>
        /// The caption of the view.
        /// </summary>
        [Browsable(true)]
        [ReadOnly(true)]
        public string Caption
        {
            get { return _caption; }
            set { _caption = value; }
        }

        /// <summary>
        /// The unique id of the view.
        /// </summary>
        [Browsable(true)]
        [ReadOnly(true)]
        public string Id
        {
            get { return _id; }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    _id = Guid.NewGuid().ToString();
                }
                else
                {
                    _id = value;
                }
            }
        }

        /// <summary>
        /// Views has Items.
        /// </summary>
        [Browsable(false)]
        public virtual bool HasItems
        {
            get { return true; }
        }

        /// <summary>
        /// The items collection can be set.
        /// </summary>
        [Browsable(false)]
        public virtual bool CanSetItems
        {
            get { return true; }
        }

        /// <summary>
        /// The list of items in the view.
        /// </summary>
        [Browsable(false)]
        public virtual GuidanceItemCollection Items
        {
            get { return _items; }
            set { _items = value; }
        }

        /// <summary>
        /// The parent folder reference.
        /// </summary>
        [Browsable(false)]
        public Folder ParentFolder
        {
            get { return _parentFolder; }
            set { _parentFolder = value; }
        }

        /// <summary>
        /// The outer container of the view.
        /// </summary>
        [Browsable(false)]
        public FolderStructure Container
        {
            get { return _container; }
            set { _container = value; }
        }

        /// <summary>
        /// The columns for this view.
        /// </summary>
        [Browsable(false)]
        public virtual ColumnCollection Columns
        {
            get { return _columns; }
            set { _columns = value; }
        }

        /// <summary>
        /// The author of the view.
        /// </summary>
        [Browsable(true)]
        [ReadOnly(true)]
        public string Author
        {
            get { return _author; }
            set { _author = value; }
        }

        /// <summary>
        /// The description of this view.
        /// </summary>
        [Browsable(true)]
        [ReadOnly(true)]
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        /// <summary>
        /// The creation date for this view.
        /// </summary>
        [Browsable(true)]
        [ReadOnly(true)]
        public DateTime LastUpdate
        {
            get { return _lastUpdate; }
            set { _lastUpdate = value; }
        }

        /// <summary>
        /// Whether the view will be display as a root element or within the container.
        /// </summary>
        [Browsable(false)]
        public bool RootView
        {
            get { return _rootView; }
            set { _rootView = value; }
        }

        #endregion

        #region IEnumerable Members

        public virtual IEnumerator<GuidanceItem> GetEnumerator()
        {
            foreach (GuidanceItem item in _items.Values)
            {
                yield return item;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion

        public override bool Equals(object obj)
        {
            View other = obj as View;
            if (other != null)
            {
                bool caption = (_caption == other._caption);
                bool columns = (_columns.Equals(other._columns));
                bool parentFolder = (_parentFolder == other._parentFolder);
                bool items = (_items.Equals(other._items));
                bool root = (_rootView.Equals(other._rootView));
                return (caption && columns && parentFolder && items && root);
            }
            else
            {
                return base.Equals(obj);
            }
        }

        public override int GetHashCode()
        {
            return _caption.GetHashCode();
        }

        public Library GetContainerLibrary()
        {
            if (ParentFolder != null)
            {
                Folder tempFolder;
                for (tempFolder = ParentFolder; tempFolder.ParentFolder != null; tempFolder = tempFolder.ParentFolder)
                { }
                return tempFolder.Container as Library;
            }
            else
            {
                return Container as Library;
            }
        }

        /// <summary>
        /// Remove the View from the container.
        /// </summary>
        public virtual void Remove(bool removeParentWhenEmpty)
        {
            if (ParentFolder == null)
            {
                Container.Views.Remove(this._caption);
            }
            else
            {
                ParentFolder.Views.Remove(this._caption);
                if (removeParentWhenEmpty && ParentFolder.Views.Count == 0)
                {
                    ParentFolder.Remove();
                }
            }
			
			// TODO: REEVIEW THIS
			//if (CopyItemsByValue ) 
			//{
			//    GuidanceExplorer.Services.ModelStorageService mdss = new GuidanceExplorer.Services.ModelStorageService();

			//    foreach (GuidanceItem guidanceItem in Items)
			//    {
			//        GuidanceItemFileReference gifr = guidanceItem as GuidanceItemFileReference;
			//        if (gifr != null && File.Exists(gifr.FullFileName) && !mdss.HasLink(gifr))
			//        {
			//            File.Delete(gifr.FullFileName);
			//        }
			//    }
			//}
        }

        public virtual View Clone()
        {
            View newView = new View();
            newView._author = Author;
            newView._caption = Caption;
            newView._columns = Columns;
            newView._container = Container;
            newView._lastUpdate = LastUpdate;
            newView._description = Description;
            newView._id = Guid.NewGuid().ToString();
            newView._items = Items.Clone();
            newView._parentFolder = ParentFolder;
            newView._rootView = RootView;

            return newView;
        }

        /// <summary>
        /// Return whether the items added to this root container must be copied by value
        /// </summary>
        [Browsable(false)]
        public virtual bool CopyItemsByValue 
        { 
            get 
            {
                if (Container != null)
                {
                    return Container.CopyItemsByValue;
                }
                Folder tempFolder;
                for (tempFolder = ParentFolder; tempFolder.ParentFolder != null; tempFolder = tempFolder.ParentFolder)
                { }
                return tempFolder.Container.CopyItemsByValue;
            }
        }

    }
}

